using System;
using System.Collections.Generic;
using System.Linq;
using microsoft_TODO.DTOs;
using microsoft_TODO.MongoCore;
using microsoft_TODO.ServiceCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using server.DTOs;
using server.Helpers;

namespace microsoft_TODO.Controllers {

    [Route ("api/[controller]")]
    public class TaskController : Controller {

        ILogger<TaskController> _logger;
        ITaskService _taskService;

        public TaskController (
            ILogger<TaskController> logger,
            ITaskService taskService) {
            _logger = logger;
            _taskService = taskService;
        }

        /// <summary>
        /// 获取今天待办的事项列表（已过时，在前端筛选即可）
        /// </summary>
        /// <param name="uid">登录用户ID</param>
        /// <returns></returns>
        [HttpGet ("today/{uid}")]
        public IActionResult GetTodays (string uid) {
            try {
                var res = _taskService.GetTasksToday (uid);
                return Ok (res);
            } catch (Exception ex) {
                _logger.LogError ("Failed to execute GET today's tasks({uid}): {message}", uid, ex.Message);
                return BadRequest ();
            }
        }

        /// <summary>
        /// 添加新的待办事项
        /// </summary>
        /// <param name="dto">清单ID(ListId) / 事项名称(Todo)</param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult Post ([FromBody] NewTaskDto dto) {
            try {
                var newTask = _taskService.AddNewTask (dto);
                _logger.LogInformation (LoggingEvents.InsertItem, "Add Task({name}) to List({listId})", dto.Todo, dto.ListId);
                return Created ("", newTask);
            } catch (Exception ex) {
                _logger.LogError ("Failed to execute POST new task({todo}): {message}", dto.Todo, ex.Message);
                return BadRequest ();
            }
        }

        /// <summary>
        /// 更新待办事项
        /// </summary>
        /// <param name="dto"></param>
        /// <remarks>
        /// 以下参数为必填，其他参数每次请求只能更新一个（只需填一个需要更新的参数即可）
        ///
        ///     listId: 所属清单ID(list.id)
        ///     index: 该待办事项在清单数组的下标(task.index)
        ///
        /// </remarks>
        /// <returns></returns>
        [HttpPut]
        public IActionResult Put ([FromBody] PutTaskDto dto) {
            try {
                _logger.LogInformation (LoggingEvents.UpdateItem, "Turn Task({ListId}) to undo at {Index}", dto.ListId, dto.Index);
                _taskService.UpdateTask (dto);
                return Ok ();
            } catch (Exception) {
                _logger.LogError ("Failed to execute PUT");
                return BadRequest ();
            }
        }

        /// <summary>
        /// 删除待办事项
        /// </summary>
        /// <param name="lid">所属清单ID</param>
        /// <param name="index">该待办事项在清单数组的下标</param>
        /// <remarks>
        /// codes:
        ///
        ///     4005: "未找到要删除的元素"
        ///
        /// </remarks>
        /// <returns></returns>
        [HttpDelete ("{lid}/{index}")]
        public IActionResult Delete (string lid, int index) {
            try {
                _logger.LogInformation (LoggingEvents.DeleteItem, "Remove Task({ListId}) to done at {Index}", lid, index);
                if (_taskService.RemoveTask (lid, index))
                    return Ok ();
                return NotFound (new { code = LoggingEvents.DeleteItemNotFound });
            } catch (Exception ex) {
                _logger.LogError (ex.Message);
                _logger.LogError ("Failed to execute DELETE");
                return BadRequest ();
            }
        }

        /// <summary>
        /// 移动待办事项（即添加到新的清单中）
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("move")]
        public IActionResult MoveTask ([FromBody] MoveTaskDto dto) {
            try {
                _taskService.MoveToAnotherList(dto);
                return Ok ();
            } catch (Exception) {
                return BadRequest ();
            }
        }

        [HttpDelete ("{lid}/{index}/deadline")]
        public IActionResult ClearDeadline (string lid, int index) {
            try {
                _logger.LogInformation (LoggingEvents.UpdateItem, "Clear Task({listId})'s deadline at {Index}", lid, index);
                if (_taskService.ClearTaskDeadline (lid, index))
                    return Ok ();
                return NotFound (new { code = LoggingEvents.UpdateItemNotFound });
            } catch (Exception ex) {
                _logger.LogError (ex.Message);
                return BadRequest ();
            }
        }
    }
}